package cn.zysheep.jackson;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;


/**
 * @version v1.0
 * @Author: lyw
 * @Date: 2021/8/10
 */
public class ObjectMapperTest {

    ObjectMapper objectMapper = null;
    Person person = null;

    {
        objectMapper = new ObjectMapper();
        HashMap<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("message", "成功");
        ArrayList<Object> objects = new ArrayList<>();
        objects.add("123");
        objects.add("123");
        objects.add(123);
        objects.add(new Date());
        person = new Person("小花", 20, new Date(), map,objects);
    }


    /**
     * POJO 对象转 json 字符串
     * String writeValueAsString(Object value)
     * 1、该方法可用于将任何 Java 值、对象序列化为 json 字符串，如果对象中某个属性的值为 null，则默认也会序列化为 null
     * 2、value 为 null，返回 null
     *
     * @throws JsonProcessingException
     */
    @Test
    public void testWriteValueAsString() throws JsonProcessingException {
        String string = objectMapper.writeValueAsString(person);
        System.out.println(string);
    }

    /**
     * String writeValueAsString(Object value)
     * 1、 Java 值、对象序列化为 json 字符串，value 可以是任意的 java 对象，比如 POJO、list、Map、Set 等等
     */
    @Test
    public void testWriteValueAsString1() throws JsonProcessingException {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("李白",20,new Date(),null,null));
        list.add(new Person("百里玄策",21,new Date(),null,null));
        String string = objectMapper.writeValueAsString(list);
        System.out.println(string);
    }


    /**
     * T readValue(String content, Class<T> valueType)
     * 1、从给定的 JSON 内容字符串反序列化为对象
     * 2、content 为空或者为 null，都会报错
     * 3、valueType 表示反序列号的结果对象，可以是任何 java 对象，比如 POJO、List、Set、Map 等等.
     */
    @Test
    public void  testingWrite() throws JsonProcessingException {
        String string = objectMapper.writeValueAsString(person);
        System.out.println("序列号: "+string);
        Person person = objectMapper.readValue(string, Person.class);
        System.out.println("反序列化: "+person);
    }



    /**
     * JsonNode readTree(String content)：将 JSON 内容反序列化为 JsonNode 对象
     * JsonNode readTree(URL source) :对网络上的 json 文件进行反序列化为 json 节点对象
     * JsonNode readTree(File file)：将本地 json 文件反序列化为 json 节点对象
     * @throws JsonProcessingException
     */
    @Test
    public void testReadTree() throws JsonProcessingException {
        String string = objectMapper.writeValueAsString(person);
        JsonNode jsonNode = objectMapper.readTree(string);
        System.out.println(jsonNode.get("name"));
    }


    /**
     * T treeToValue(TreeNode n, Class<T> valueType)：json 节点对象转 Java 对象（如 POJO、List、Set、Map 等等）
     */
    @Test
    public void testTreeToValue() throws JsonProcessingException {
        ObjectNode jsonNodes = JsonNodeFactory.instance.objectNode();
        jsonNodes.put("name","封于修");
        jsonNodes.put("age",22);

        Person person = objectMapper.treeToValue(jsonNodes, Person.class);
        System.out.println(person);
    }

    /**
     * T convertValue(Object fromValue, Class<T> toValueType)
     * 1、将 Java 对象（如 POJO、List、Map、Set 等）序列化为 Json 节点对象，通常有以下两种方式：
     * 2、一种方式是先序列化为 json 字符串，然后 readTree 反序列化为 Json 节点
     * 3、还有就是使用此种方式进行转换，将 java 对象直接转换为 json 节点。
     */
    @Test
    public void testConvertValue() {
        JsonNode jsonNode = objectMapper.convertValue(person, JsonNode.class);
        System.out.println(jsonNode.get("map"));

        // spring core包中的工具类
        ObjectMapperTest objectMapperTest = BeanUtils.instantiateClass(ObjectMapperTest.class);
        System.out.println(objectMapperTest.person);
    }


}
